/*
 * Copyright (C), 2017-2019 广东鸿特信息咨询有限公司
 * FileName: RedissonUtilAbstract.java
 * Author:   张鹏
 * Date:     2019-05-24 23:53
 * History:
 * <author>          <time>          <version>          <desc>
 * 张鹏             2019-05-2423:53     V1.00             新建
 * -----------------------------------------------------------
 * 作者姓名           修改时间           版本号            描述
 */
package com.zhouz.admin.app.config.redisson;


import com.zhouz.admin.app.db.exception.ReSubmitException;
import com.zhouz.admin.app.util.BeanHeader;
import com.zhouz.admin.app.util.func.RedissonLockFunc;
import lombok.extern.log4j.Log4j2;
import org.redisson.api.RLock;

import java.util.concurrent.TimeUnit;

/**
 * <br>
 *
 * @Author 张鹏
 * @Date 2019-05-24 23:53
 */
@Log4j2
public class RedissonUtil {
    /**
     * 分布式加锁执行
     * @Author 张鹏
     * @Date 2019-05-24 23:59
     * @param key
     * @return
     * @throws InterruptedException
     */
    public  static <T> T invoke(String key, RedissonLockFunc<T> func) throws InterruptedException {
        RedissonService redissonService = BeanHeader.getBean(RedissonService.class);
        // 分布式锁 -锁状态 和防重复提交
        RLock lock = redissonService.getRLock(key);
        try {
            // 2秒内获取不到锁，返回false 。3秒后自动释放
            boolean bs = lock.tryLock(3, 4, TimeUnit.SECONDS);
            if (bs) {
                return func.run();
            } else {
                throw new ReSubmitException("当前业务繁忙，请稍后再试");
            }
        } catch (InterruptedException e) {
            log.error("执行异常", e);
            throw e;
        } finally {
            lock.unlock();
        }
    }

}
